#include <linux/init.h>         //包含宏定义得头文件
#include <linux/module.h>       //包含初始化加载模块得头文件
#include <linux/miscdevice.h>   //杂项设备头文件
#include <linux/fs.h>           //文件操作集
#include <linux/uaccess.h>      //copy_to_user函数的文件
/*包含头文件*/

/*****************
*注册杂项设备驱动，并生成设备节点

*****************/
/*文件操作集的结构体*/
int misc_open(struct inode*inode,struct file * file)
{
    printk("hello misc opnen\n");
    return 0;
}

int misc_release(struct inode*inode,struct file * file)
{
    printk("hello misc misc_release byb byb!\n");
    return 0;
}

int misc_read(struct file * file,char _user * ubuf,size_t size,loff_t*loff_t)
{
    char kbuf[64]="hello";
    if(copy_to_user(ubuf,kbuf,strlen(kbuf)!=0))//拷贝信息到应用层
    {
        printk("copy_to_user error!\n");
        return -1;
    }

    printk("hello misc_read file!\n");
    return 0;
}

int misc_write(struct file * file,char _user * ubuf,size_t size,loff_t*loff_t)
{
     char kbuf[64]={0};
    if(copy_form_user(kbuf,ubuf,size)!=0)//从应用层拷贝数据到内核层
    {
        printk("copy_form_user %s!\n",kbuf);
        return -1;
    }
    return 0;
}


struct file_operations misc_fops={
    .owner = THIS_MODULE,
    .open  = misc_open,
    .release = misc_release,
    .read = misc_read,
    .write = misc_write
};

/*描述杂项设备的结构体*/
struct miscdevice misc_dev={
.minor = MISC_DYNAMIC_MINOR, //
.name  ="hello_misc",       //设备节点的名称查看dev
.fops  =&misc_fops
};

static int misc_init(void)
{
    int ret;
    ret = misc_register(&misc_dev);//注册杂项设备，自动生成设备节点
    if(ret<0)
    {
        printk("misc register is error\n");
        return -1;
    }
    printk("misc register is ok\n");
    return 0;
}
static void misc_exit(void)//退出函数没有返回值
{
    misc_deregister(&misc_dev);
    printk("byb byb !"); 
}
/*功能实现*/

module_init(misc_init);
module_exit(misc_exit); 
/*驱动的出口与入口函数都在此处*/
MODULE_LICENSE("GPL");
/*申明信息*/
	
/*注意在开发板中加载驱动的时候一定要保持板卡的内核和编译的内核是一致的否则会报错
*查看设备节点：ls /dev/hello
*/

